import java.util.PriorityQueue;

class MyTimerTask implements Comparable<MyTimerTask>{
    //3. 创建一个类，通过类的对象来描述要执行的任务（至少要包含要执行的任务内容和时间）
    //1. 首先要有一个要执行的任务
    private Runnable runnable;
    //2. 要有一个执行任务的时间
    private long time;
    public MyTimerTask(Runnable runnable, long delay){
        this.runnable = runnable;
        this.time = System.currentTimeMillis() + delay;
    }

    public Runnable getRunnable() {
        return runnable;
    }

    public long getTime() {
        return time;
    }

    @Override
    public int compareTo(MyTimerTask o) {
        return (int)(this.time - o.time);
    }
}
public class Demo_MyTimer {
    //模拟实现Timer
    //1. Timer中要有一个线程，扫描任务是否到时间，可以执行
    //2. 需要一个数据结构，把所有的任务都存起来
    private PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();
    private Object locker = new Object();
    public void schedule(Runnable runnable, long delay){
        synchronized (locker){
            MyTimerTask task = new MyTimerTask(runnable, delay);
            queue.offer(task);
            locker.notify();
        }

    }
    public Demo_MyTimer(){
        Thread t = new Thread(() -> {
            while(true){
                try{
                    synchronized (locker){
                        //使用while是为了wait被唤醒后，多确认一次条件
                        while(queue.isEmpty()){
                            //阻塞等待
                            locker.wait();
                        }
                        MyTimerTask task = queue.peek();
                        long currentTime = System.currentTimeMillis();
                        if(currentTime >= task.getTime()){
                            task.getRunnable().run();
                            queue.poll();
                        }else{
                            locker.wait(task.getTime() - currentTime);
                        }
                    }
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        });
        t.start();
    }
}

class Test{
    public static void main(String[] args) {
        Demo_MyTimer myTimer = new Demo_MyTimer();
        myTimer.schedule(() -> {
            System.out.println("3000");
        }, 3000);
        myTimer.schedule(() -> {
            System.out.println("2000");
        }, 2000);
        myTimer.schedule(() -> {
            System.out.println("1000");
        }, 1000);
        System.out.println("程序开始运行");
    }
}
